手写MQ框架(一) | 您所在的位置:网站首页 › mq 订阅 › 手写MQ框架(一) |
一、背景
很久以前写了DAO框架和MVC框架,前段时间又重写了DAO框架-GDAO(手写DAO框架(一)-从“1”开始,源码:https://github.com/shuimutong/gdao.git)和MVC框架-GMVC(手写MVC框架(一)-再出发,源码:https://gitee.com/simpleha/gmvc.git)。 之前也尝试过写RPC框架(源码:https://github.com/shuimutong/grpc_beta.git),客户端、服务端的方法调用写完了,但是网络传输没有写。 其实写框架也好,写博客也好,主要是为了学习。所以现在再开始的时候,我就在思考写什么好? 我的想法很简单:把目前用到的框架,能自己实现的尽量都实现一遍。站在这个时间点,写哪个框架有两个选择:继续写RPC;写MQ。这两个框架个人认为有很多相似的地方:MQ虽然是异步的,其实也是有“长连接”在连着的。比如订阅方,会有长连接连着MQ的服务端。RPC框架不分订阅、发送,而是客户端、服务端,当客户端找到服务端之后,客户端会尽量和服务端保持连接。 相比MQ,RPC框架不需要持久化的动作,而MQ不仅需要考虑持久化,还需要考虑如何进行高效的持久化。 通过一番对比,我最终选择实现MQ框架,以学习序列化、网络传输、高效持久化方面的知识。选择的参照框架是kafka。 二、如何下手既然选择了实现MQ,那从何下手呢? 先了解一下kafka吧。 1、mq框架大致流程生产方和服务端建立连接,将消息发送到服务端。 订阅方和服务端建立连接,服务端将订阅方订阅的消息推送给订阅方,或者订阅方自己拉取指定的消息。 2、了解一下kafka 1)为什么kafka有如此高的qpskafka服务可以部署在机械硬盘上,接收到的每条消息都会存盘,但是qps可以轻松过万,甚至达到百万级别(数据来源于网上,本人暂未亲测)。怎么做到的? 通过官网可以了解到,我记录的有3点。 首先,采用磁盘顺序读写。其次,基于java,使用堆外内存,避免gc的干扰。再次,所有数据写两份,防止丢失。此外,还有零拷贝技术等。 以上各个方面结合起来,最终成就了kafka的英名! 2)是推消息还是拉消息推消息的话,如果消息骤增,可能导致订阅方崩掉,所以kafka采用的是拉的方式。以什么频率拉,由订阅方自己决定。 其实采用拉消息的方式也有缺点,比如订阅方为了拉消息,就会一直在哪里循环请求。如果没有新消息,订阅方就会频繁的请求,白白浪费资源。 针对这个循环空请求的问题,kafka增加了一个特性。当拉消息的时候,可以设置:如果没有消息,就先夯住请求,等到消息来了,再返回结果。这样,就能够避免这类问题了。 3、写框架计划在稍微看了kafka之后,感觉这个技术含量还是很高的。虽然上面只列了几点,其实还有很多很重要的点没有提及。但是,我就是要学写。如果等我先把kafka看透之后再写,那可能得等很长时间。(其实我已经磨蹭了很长时间) 所以我决定,先把架子搭起来。万丈高楼也得平地起! 1)大致方案写服务端,网络传输使用http,序列化使用json(传输字符串,其实无所谓json),数据持久化使用DB。 虽然使用http传输,但是需要封装成具体的工具,避免客户端自己写请求工具,方便后期升级。 2)生产方发消息消息包括:主题、消息内容 3)订阅方拉消息主题、消息内容、offset(拉多少条) 4)服务端处理消息来了之后,将消息存在DB,编offset。 拉消息动作,根据offset,返回取的多少条。 offset的提交应在客户端里进行封装,可先实现为自动提交。 5)框架组成a、服务端 b、生产消息客户端(服务配置) c、消费消息客户端(服务配置) 6)配置项a、服务地址 b、主题号 大致计划已定,那就开始实现吧 三、服务端功能梳理1、注册主题号 校验主题号是否存在,不存在则新增 2、接收消息 参数:主题号、消息体 先校验主题号是否存在,存在则保存消息到DB,然后返回结果 3、拉消息 参数:主题号、offset、希望取的消息数量 校验主题号是否存在,校验offset是否正常,正常则返回希望的消息数量(如果有消息)。 4、更改offset 参数:主题号、offset 校验主题号是否存在,校验offset。 重复消费功能后期做。 四、结语 关于手写MQ,暂时想的就这么多,后面想到其他的再加上。 先实现一个简易的服务端,接下来就是代码实现了。 写代码中…… 第一个版本在上周写完了,欢迎指教->手写MQ框架(二)-服务端实现 |
CopyRight 2018-2019 实验室设备网 版权所有 |